
# Makefile for Quantitative Finance

# $Id: Makefile 2 2012-05-22 17:55:16Z gerry@gaboury.biz $

.SUFFIXES : .cpp .hpp

.PHONY : clean realclean depend

ifndef GCC_HOME
  GCC_HOME=/usr
endif

QTVER=qt4
ifndef QTDIR
  QTDIR=/usr/share/$(QTVER)
endif
QTINC=$(QTDIR)/include
QTINCS=-I$(QTINC)/Qt -I$(QTINC)/QtGui -I$(QTINC)/QtCore

CC = $(GCC_HOME)/bin/gcc
GCC = $(GCC_HOME)/bin/gcc
CPP = $(GCC_HOME)/bin/g++
MOC = $(QTDIR)/bin/moc

# MACH=$(shell ostype.sh)
MACH=$(shell uname)

MYSQL_LIBS = -L/usr/lib/mysql -lmysqlclient

# GMP used by some tests
LIBS = -lm -lgmpxx -lgmp -lboost_thread -lboost_date_time -lboost_random

OPT=-O3

# This will change to "-std=c++11" when it becomes available.

CPPFLAGS = -g -Iinclude $(OPT) -D $(MACH) -std=c++0x # -Wno-deprecated

ifeq "$(MACH)" "CYGWIN"
  LDFLAGS = -lm -lc
else
  LDFLAGS = $(OPT) $(LIBS) # -L$(NMTLIB) -lNMT $(MYSQL_LIBS)
endif
ifneq "$(MACH)" "CYGWIN"
  SHFLAGS = -fPIC
endif

OBJEXT = o
OBJDIR = obj/$(MACH)
OBJDIR_STATIC = obj_static/$(MACH)
OBJDIR_SHARED = obj_shared/$(MACH)
BINDIR = bin/$(MACH)
LIBDIR = lib/$(MACH)
MOCDIR = moc
PIXMAPS = pixmaps

# build shared
LIBEXT_STATIC = a
LIBEXT_SHARED = so

# Meta-Object Compiler(MOC) - QT
# header files from which to generate MOC files
INCS = $(wildcard include/*.hpp)
MOCINC = $(shell grep -l Q_OBJECT $(INCS) )
MOCSRC = $(addprefix $(MOCDIR)/moc_,$(patsubst %.hpp,%.cpp,$(notdir $(MOCINC))))
MOCOBJ	= $(addprefix $(OBJDIR)/moc_,$(patsubst %.hpp,%.$(OBJEXT),$(notdir $(MOCINC))))

SRCS = $(wildcard src/*.cpp)
OBJS_STATIC = $(addprefix $(OBJDIR_STATIC)/,$(subst .cpp,.$(OBJEXT),$(subst src/,,$(SRCS))))
OBJS_SHARED = $(addprefix $(OBJDIR_SHARED)/,$(subst .cpp,.$(OBJEXT),$(subst src/,,$(SRCS))))

GUI_SRC = $(wildcard gui/*.cpp)
GUI_OBJ = $(subst .cpp,.$(OBJEXT),$(GUI_SRC))
GUI_EXE = $(addprefix $(BINDIR)/,$(subst .cpp,,$(subst gui/,,$(GUI_SRC))))

MAIN_SRC = $(wildcard main/*.cpp)
MAIN_SRC_C = $(wildcard main/*.c)
MAIN_OBJ = $(subst .cpp,.$(OBJEXT),$(MAIN_SRC))
MAIN_OBJ_C = $(subst .c,.$(OBJEXT),$(MAIN_SRC_C))
MAIN_EXE = $(addprefix $(BINDIR)/,$(subst .cpp,,$(subst main/,,$(MAIN_SRC))))
MAIN_EXE += $(addprefix $(BINDIR)/,$(subst .c,,$(subst main/,,$(MAIN_SRC_C))))

TEST_SRC = $(wildcard test/*.cpp)
TEST_SRC_C = $(wildcard test/*.c)
TEST_OBJ = $(subst .cpp,.$(OBJEXT),$(TEST_SRC))
TEST_OBJ_C = $(subst .c,.$(OBJEXT),$(TEST_SRC_C))
TEST_EXE = $(addprefix $(BINDIR)/,$(subst .cpp,,$(subst test/,,$(TEST_SRC))))
TEST_EXE += $(addprefix $(BINDIR)/,$(subst .c,,$(subst test/,,$(TEST_SRC_C))))

VERSION = 0
LIBNAME=quant
LIBNAME_STATIC = lib$(LIBNAME).$(LIBEXT_STATIC)
LIBNAME_SHARED = lib$(LIBNAME).$(LIBEXT_SHARED)
QUANT_STATIC_LIB = $(LIBDIR)/$(LIBNAME_STATIC)
QUANT_SHARED_LIB = $(LIBDIR)/$(LIBNAME_SHARED).$(VERSION)

# suffix rules
# general compilation
.cpp.$(OBJEXT):
	$(CPP) -c $(CPPFLAGS) $< -o $@

$(MOCDIR)/moc_%.cpp : include/%.hpp
	$(MOC) $(MOCFLAGS) $< -o $@

# make a moc object file from a moc/moc*.cpp
$(OBJDIR)/moc_%.$(OBJEXT) : $(MOCDIR)/moc_%.cpp
	$(CPP) -c $(CPPFLAGS) $< -o $@


# library objects
$(OBJDIR_STATIC)/%.$(OBJEXT) : src/%.cpp
	$(CPP) -c $(CPPFLAGS) $< -o $@

$(OBJDIR_SHARED)/%.$(OBJEXT) : src/%.cpp
	$(CPP) -c $(CPPFLAGS) $(SHFLAGS) $< -o $@

#
#  default target ###
#
all: $(LIBDIR) $(OBJDIR_STATIC) $(OBJDIR_SHARED) $(BINDIR) \
	$(QUANT_STATIC_LIB) $(OBJDIR) \
	$(GUI_EXE) $(MAIN_EXE) $(TEST_EXE)

# debug: 

# targets

libs: $(QUANT_STATIC_LIB) $(QUANT_SHARED_LIB)

$(QUANT_SHARED_LIB) : $(OBJS_SHARED)
	$(CPP) -shared $(LDFLAGS) -Wl,-soname,$(LIBNAME_SHARED).$(VERSION) $^ -o $@
	cd $(LIBDIR); ln -sf $(LIBNAME_SHARED).$(VERSION) $(LIBNAME_SHARED)

$(QUANT_STATIC_LIB) : $(OBJS_STATIC)
	ar cr $@ $^

# executables - link static
$(BINDIR)/% : gui/%.$(OBJEXT) $(MOCOBJ) $(QUANT_STATIC_LIB)
	$(CPP) $^ $(LDFLAGS) -o $@

$(BINDIR)/% : main/%.$(OBJEXT) $(QUANT_STATIC_LIB)
	$(CPP) $^ $(LDFLAGS) -o $@

$(BINDIR)/% : test/%.$(OBJEXT) $(QUANT_STATIC_LIB)
	$(CPP) $^ $(LDFLAGS) -o $@

clean:
	rm -f $(OBJS_STATIC) $(OBJS_SHARED) \
	$(MAIN_OBJ) $(MAIN_OBJ_C) $(MAIN_EXE) \
	$(TEST_OBJ) $(TEST_OBJ_C) $(TEST_EXE) \
	$(QUANT_SHARED_LIB) $(QUANT_STATIC_LIB) \
	$(LIBDIR)/$(LIBNAME_SHARED) $(MAKE_DEPEND) \
	$(GUI_OBJ) $(MOC_SRC) $(MOC_OBJ)

realclean: clean
	find . -name "*~" -exec rm -f {} \;
	find . -name "error.log" -exec rm -f {} \;

# dependencies

MAKE_DEPEND = .depend.$(MACH)

depend : $(MAKE_DEPEND)

$(MAKE_DEPEND) : $(INCS) $(SRCS) $(MAIN_SRC)
	$(GCC) -c $(CPPFLAGS) -E -MM $^  > $@
#	./fixdep.pl $@

include $(MAKE_DEPEND)

$(OBJDIR_STATIC) :
	-mkdir -p $@

$(OBJDIR_SHARED) :
	-mkdir -p $@

$(LIBDIR) :
	-mkdir -p $@

$(BINDIR) :
	-mkdir -p $@

$(OBJDIR) :
	-mkdir -p $@

# $(MOCDIR) :
# 	-mkdir -p $@
